package top.mcwebsite.playandroid.business.tutorial.impl.ui

import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.paging.*
import androidx.paging.compose.collectAsLazyPagingItems
import coil.compose.AsyncImage
import kotlinx.coroutines.flow.Flow
import top.mcwebsite.lib.route.api.EasyRouter
import top.mcwebsite.lib.router.annotation.Param
import top.mcwebsite.lib.router.annotation.Route
import top.mcwebsite.playandroid.business.articles.api.model.ArticleModel
import top.mcwebsite.playandroid.business.tutorial.api.model.TutorialModel
import top.mcwebsite.playandroid.business.tutorial.impl.vm.TutorialMenuIntent
import top.mcwebsite.playandroid.business.tutorial.impl.vm.TutorialMenuUiEffect
import top.mcwebsite.playandroid.business.tutorial.impl.vm.TutorialMenuUiState
import top.mcwebsite.playandroid.business.tutorial.impl.vm.TutorialMenuViewModel
import top.mcwebsite.playandroid.common.constant.RouteConfig
import top.mcwebsite.playandroid.lib.common.ext.encodeURL

@Route("tutorial_menu")
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun TutorialMenuPage(
    @Param("tutorial") tutorialModel: TutorialModel?
) {
    val viewModel: TutorialMenuViewModel = viewModel()
    val uiState by viewModel.uiStateFlow.collectAsState()
    LaunchedEffect(Unit) {
        viewModel.sendIntent(TutorialMenuIntent.InitTutorialMenuIntent(tutorialModel))
    }
    viewModel.HandleUiEffect {
        when (it) {
            is TutorialMenuUiEffect.NavigationToDetailPageEffect -> {
                EasyRouter.navigate("${RouteConfig.ArticleDetail.PATH}/${it.articleModel.link.encodeURL()}")
            }
        }
    }
    Scaffold(topBar = {
        TopAppBar(
            title = {
                Text(uiState.tutorialModel?.name ?: "")
            },
            navigationIcon = {
                IconButton(onClick = {
                    EasyRouter.popBackStack()
                }) {
                    Icon(Icons.Default.ArrowBack, contentDescription = null)
                }
            },
        )
    }) {
        TutorialMenuContent(
            uiState = uiState,
            pagerFlow = uiState.pagerFlow,
            modifier = Modifier.padding(it),
        ) {
            viewModel.sendIntent(it)
        }
    }
}

@Composable
fun TutorialMenuContent(
    uiState: TutorialMenuUiState,
    modifier: Modifier,
    pagerFlow: Flow<PagingData<ArticleModel>>? = null,
    sendIntent: (TutorialMenuIntent) -> Unit
) {
    if (pagerFlow == null) {
        return
    }
    val lazyPagingItems = pagerFlow.collectAsLazyPagingItems()
    Box(modifier.fillMaxSize()) {
        LazyColumn {
            item {
                TutorialInfo(uiState.tutorialModel)
            }
            item {
                MenuText()
            }
            items(
                count = lazyPagingItems.itemCount
            ) { index ->
                val item = lazyPagingItems[index]
                if (item != null) {
                    MenuItem(index + 1, item) {
                        sendIntent(TutorialMenuIntent.RequestToTutorialDetailPageIntent(item))
                    }
                }
            }
            // Add a loading item at the end
            if (lazyPagingItems.loadState.append == LoadState.Loading) {
                item { CircularProgressIndicator(modifier = Modifier
                    .width(50.dp)
                    .padding(16.dp)) }
            }

            // Handle errors
            if (lazyPagingItems.loadState.append is LoadState.Error) {
                val errorState = lazyPagingItems.loadState.append as LoadState.Error
                item {
                    Text(
                        text = "Error: ${errorState.error.localizedMessage}",
                        modifier = Modifier.padding(16.dp)
                    )
                }
            }
            if (lazyPagingItems.loadState.append is LoadState.NotLoading) {
                item {
                    Spacer(Modifier.height(20.dp))
                }
            }
        }
    }
}

@Composable
fun TutorialInfo(
    tutorialModel: TutorialModel? = null,
) {
    if (tutorialModel != null) {
        Row(modifier = Modifier.padding(vertical = 10.dp, horizontal = 16.dp)) {
            AsyncImage(
                tutorialModel.cover,
                contentDescription = null,
                contentScale = ContentScale.Fit,
                modifier = Modifier
                    .width(100.dp)
                    .clip(RoundedCornerShape(10.dp))
            )
            Column(modifier = Modifier.padding(start = 10.dp)) {
                Text(tutorialModel.name, style = MaterialTheme.typography.titleMedium)
                Text(
                    "作者: " + tutorialModel.author,
                    style = MaterialTheme.typography.bodyMedium,
                    modifier = Modifier.padding(vertical = 5.dp)
                )
                Text(
                    "简介: " + tutorialModel.desc.trim(),
                    style = MaterialTheme.typography.bodyMedium,
                    color = LocalContentColor.current.copy(alpha = 0.78f),
                    modifier = Modifier.padding(vertical = 5.dp)
                )
                Text(tutorialModel.lisense,
                    style = MaterialTheme.typography.labelMedium,
                    color = Color(0xFF2196F3),
                    modifier = Modifier.clickable { })
            }
        }
    }
}

@Composable
fun MenuText() {
    Column {
        Text("目录", style = MaterialTheme.typography.titleLarge, modifier = Modifier.padding(horizontal = 16.dp))
        Spacer(modifier = Modifier.height(5.dp))
        Divider(modifier = Modifier
            .height(1.dp)
            .padding(horizontal = 16.dp))
    }
}

@Composable
fun MenuItem(
    number: Int,
    articleModel: ArticleModel,
    onClick: () -> Unit,
) {
    Row(
        verticalAlignment = Alignment.CenterVertically,
        modifier = Modifier
            .fillMaxWidth()
            .clickable {
                onClick.invoke()
            }
            .padding(start = 16.dp)
            .padding(vertical = 5.dp),
    ) {
        Text("$number.")
        Spacer(modifier = Modifier.width(5.dp))
        Text(articleModel.title)
    }
}